﻿using System;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft;
using System.Drawing;
using CloudOfficeEngine;
using GoogleConnector;
using Utilities;
using UILibrary;

namespace OfficeInCloudExcel2003Addin2
{
    public partial class ThisAddIn
    {
        Excel.Application m_app;

        private CustomActionPane m_pane;
        private CommandBar m_cmdBar;
        private COE m_Engine;
        private ExcelLocalView m_LocalView;
        private Connector m_RemoteConnector;
        public MyGDocsForm m_MyGDocsForm;
        private bool DisabledMode = true;
        private TraceWrapper m_traceWrapper;
        private DbOperations m_dbOperations;
        Office.CommandBarButton m_showMenu;
        Office.CommandBarButton m_updateMenu;
        Office.CommandBarButton m_aboutMenu;
        public Update m_updateChecker;
        private SnapshotManager m_snapshot;
        private int m_paneWidth = 313;

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            #region VSTO generated code

            this.Application = (Excel.Application)Microsoft.Office.Tools.Excel.ExcelLocale1033Proxy.Wrap(typeof(Excel.Application), this.Application);

            #endregion

            
            m_app = this.Application;

            CommonOperations.initPaths("\\Uprise Apps\\Excel2003og.txt", 
                                        "\\Uprise Apps\\Info.mdb",
                                        System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);

            m_traceWrapper = new TraceWrapper();
            m_traceWrapper.initTraceListener();
            m_traceWrapper.traceSystemInfo(this.Application.Version, 
                                            System.Reflection.Assembly.GetExecutingAssembly().GetName().ToString());

            m_updateChecker = new Update();
            m_updateChecker.checkForUpdates(Properties.Resources.AppUpdateName, 
                                            System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());

            m_dbOperations = new DbOperations(new DbManager(Utilities.Path.dbPath));
            m_snapshot = new SnapshotManager();

            //First Run
            RegistryKey kHKCU = Registry.CurrentUser;
            RegistryKey kFirstRun;
            try
            {
                kFirstRun = kHKCU.OpenSubKey("Software\\UpriseApps\\OfficeInCloudExcel2007", true);
                if (kFirstRun == null)
                {
                    kFirstRun = kHKCU.CreateSubKey("Software\\UpriseApps\\OfficeInCloudExcel2007", RegistryKeyPermissionCheck.ReadWriteSubTree);
                    kFirstRun.SetValue("FirstRun", 1);
                    //MessageBox.Show("Office In Cloud for Google Docs (Excel 2007) was not properly installed. \n Please contact Uprise Apps support.", "Office In Cloud Error Message");
                }
                else
                {
                    if (kFirstRun.GetValue("FirstRun").ToString().Equals("1"))
                    {
                        //Registration Wizard
                        Registration regForm = new Registration(m_dbOperations, System.Reflection.Assembly.GetEntryAssembly());
                        if (DialogResult.OK == regForm.ShowDialog())
                        {
                            DisabledMode = false;
                        }
                    }
                    else DisabledMode = false;
                }
            }
            catch (Exception ex)
            {
                Utilities.TraceWrapper.LogException("ThisAddIn_Startup error: " + ex.Message, ex);

                MessageBox.Show("Office In Cloud for Google Docs (Excel 2007) was not properly installed. \n Please contact Uprise Apps support.", "Office In Cloud Error Message");
            }

            CommunicationSetup();

            //build UI
            constructActionPane();

            m_cmdBar = new CommandBar();
            m_cmdBar.buildMenuBar((Office.CommandBar)Application.CommandBars.ActiveMenuBar,
                                    new Office._CommandBarButtonEvents_ClickEventHandler(showActionPane),
                                    new Office._CommandBarButtonEvents_ClickEventHandler(checkForUpdates),
                                    new Office._CommandBarButtonEvents_ClickEventHandler(showAbout));

            m_app.WorkbookOpen += new Microsoft.Office.Interop.Excel.AppEvents_WorkbookOpenEventHandler(app_WorkbookOpen);
            ((Microsoft.Office.Interop.Excel.AppEvents_Event)m_app).NewWorkbook += new Microsoft.Office.Interop.Excel.AppEvents_NewWorkbookEventHandler(app_WorkbookNew);

        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
            //restore wnd proc
            try
            {
                m_pane.release();
            }
            catch (Exception ex)
            {
            }
            // Flush the output.
            Trace.WriteLine("");
            Trace.WriteLine("");
            Trace.WriteLine("");
            m_traceWrapper.shutdownTraceListener();

        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion


        private void showAbout(Office.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            AboutBox about = new AboutBox(Assembly.GetExecutingAssembly());
            about.ShowDialog();
        }

        private void checkForUpdates(Office.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            m_updateChecker.checkForUpdates(Properties.Resources.AppUpdateName, 
                                            System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
        }

        private void showActionPane(Office.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            if ((m_pane == null) || m_pane.m_actionPane.IsDisposed)
                constructActionPane();
        }

        private void CommunicationSetup()
        {
            m_LocalView = new ExcelLocalView(this.Application, m_dbOperations);
            m_RemoteConnector = new Connector();
            m_Engine = new COE(m_LocalView, m_RemoteConnector);
        }


        private Office.CommandBar getCommandBar(string name)
        {
            Office.CommandBar cmdBar = null;
            foreach (Office.CommandBar cmd in m_app.CommandBars)
            {
                if (cmd.Name == name)
                {
                    cmdBar = cmd;
                    break;
                }
            }

            return cmdBar;
        }

        private void displayActionPane()
        {
            try
            {
                Office.CommandBar cmdPane1 = (Office.CommandBar)Application.CommandBars.ActiveMenuBar;
                foreach (Office.CommandBarControl ctrl1 in cmdPane1.Controls)
                {
                    //if (ctrl1.Caption == "&View")
                    if (ctrl1.Id == 30004)
                    {
                        Office.CommandBarPopup foundMenu = ctrl1 as Office.CommandBarPopup;
                        foreach (Office.CommandBarControl ctrl2 in foundMenu.Controls)
                        {
                            //"Tas&k Pane"
                            if (ctrl2.Id == 5746)
                            {
                                Office.CommandBarButton btn = ctrl2 as Office.CommandBarButton;
                                btn.Execute();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Utilities.TraceWrapper.LogException("resizeActionPane error: " + ex.Message, ex);
            }
        }
        private void resizeActionPane()
        {
            try
            {
                Office.CommandBar cmdPane = getCommandBar("Task Pane");

                if (cmdPane != null)
                {
                    cmdPane.Position = Office.MsoBarPosition.msoBarRight;
                    if (cmdPane.Visible == false)
                        displayActionPane();

                    cmdPane.Width = m_paneWidth;
                }
                else
                    MessageBox.Show("is_null");
            }
            catch (Exception ex)
            {
                Utilities.TraceWrapper.LogException("resizeActionPane error: " + ex.Message, ex);
            }
        }

        private void constructActionPane()
        {
            m_MyGDocsForm = new MyGDocsForm(m_LocalView, DisabledMode, m_dbOperations, m_traceWrapper, m_snapshot, Google.Documents.Document.DocumentType.Spreadsheet, System.Reflection.Assembly.GetExecutingAssembly());

            //excel 2003 doesn't support multithreading
            m_MyGDocsForm.m_multithreadSupported = false;

            //ActionPaneBuilder.layoutControls(m_MyGDocsForm);

            //create our own window at the top of command bar "Task Pane"
            int currentWidth = 313;
            IntPtr hAppWnd = IntPtr.Zero;
            IntPtr hPaneWnd = IntPtr.Zero;
            lookForHandles(out hAppWnd, out hPaneWnd);

            if ((hAppWnd != IntPtr.Zero) && (hPaneWnd != IntPtr.Zero))
            {
                m_pane = new CustomActionPane(hAppWnd, hPaneWnd);
                m_pane.buildActionPane();

                m_pane.m_actionPane.Controls.Add(m_MyGDocsForm);

                m_MyGDocsForm.Visible = true;
            }
        }

        private bool enumChild(IntPtr hWnd, out IntPtr lParam)
        {
            // it's enough to hold any class name
            int nMaxCount = 4096;
            StringBuilder className = new StringBuilder(nMaxCount);
            lParam = IntPtr.Zero;

            Win32Declaration.GetClassName(hWnd, className, nMaxCount);

            if (className.ToString() == "MsoCommandBar")
            {
                IntPtr paneWnd = Win32Declaration.FindWindowEx(hWnd, IntPtr.Zero, "MsoWorkPane", null);
                if (paneWnd != IntPtr.Zero)
                {
                    //it's "Task Pane"
                    lParam = hWnd;
                    return false;
                }
            }

            return true;
        }

        private void lookForHandles(out IntPtr hAppWnd, out IntPtr hPaneWnd)
        {
            resizeActionPane();

            //refactor this part of finding window, since the potential structure can be different 
            //excel main window
            hAppWnd = Win32Declaration.FindWindow("XLMAIN", m_app.Caption);
            //EnumWindows(new EnumWindowsProc(enumTop), out hAppWnd);
            
            //excel workbook
            IntPtr hExcelWb = Win32Declaration.FindWindowEx(hAppWnd, IntPtr.Zero, "EXCEL2", null);
            //find "Task Pane" window based on assumption it has msgClass MsoCommandBar and child MsoWorkPane
            Win32Declaration.EnumChildWindows(hExcelWb, new Win32Declaration.EnumWindowsProc(enumChild), out hPaneWnd);
        }

        void app_WorkbookNew(Microsoft.Office.Interop.Excel.Workbook Wb)
        {
            resizeActionPane();
        }

        void app_WorkbookOpen(Microsoft.Office.Interop.Excel.Workbook Wb)
        {
            resizeActionPane();
        }

    }
}

//OfficeInCloudExcel2003Addin2 